package com.credithc.signature.core.util;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @desc: PDF印章工具类<br />
 * @author: Jingbo Hu<br/>
 * @time：2020年04⽉21⽇<br/>
 * @version：v1.0.0<br>
 */
@Slf4j
public class PdfStampUtil {

    /**
     * 获取PDF文件中关键字
     *
     * @param source
     * @param keyword
     * @return
     * @throws IOException
     */
    private static List<float[]> getPositions(String source, String keyword) throws IOException {
        File pdfFile = new File(source);
        byte[] pdfData = new byte[(int) pdfFile.length()];

        try (FileInputStream fis = new FileInputStream(pdfFile)) {
            fis.read(pdfData);
        } catch (IOException e) {
            log.error("PDF印章工具类:-->getPositions:文件不存在", e);
        }

        //查到关键字返回位置
        List<float[]> positions = GetKeywordPosition.findKeywordPositions(pdfData, keyword);
        if (positions.size() == 0) {
            log.error("PDF印章工具类:-->getPositions:关键字不存在");
        }
        return positions;
    }

    /**
     * 寻找指定的关键字后添加关键字
     *
     * @param source  源pdf文件
     * @param target  目标pdf文件
     * @param keyword 关键字
     * @return 返回结果
     * @throws IOException
     * @throws DocumentException
     */
    public static void findKeyWordAndAddWords(String source, String target, String keyword, String addWords) {

        try {
            List<float[]> positions = getPositions(source, keyword);
            addKeyWords(source, target, positions.get(positions.size() - 1), addWords);
            log.info("PDF印章工具类:-->findKeyWordAndAddWords:添加关键字成功");
        } catch (Exception e) {
            log.error("PDF印章工具类:-->findKeyWordAndAddWords:添加关键字失败", e);
        }
    }

    /**
     * 寻找指定的关键字后给其所在位置盖章
     *
     * @param source    源pdf文件
     * @param target    目标pdf文件
     * @param keyword   关键字
     * @param imagePath 印章路径
     * @param xOffset   x轴偏移量(没有则指定为0)
     * @param yOffset   y轴偏移量(没有则指定为0)
     * @return 返回结果
     * @throws IOException
     * @throws DocumentException
     */
    public static void findKeyWordAndAddImage(String source, String target, String keyword, String imagePath, float xOffset, float yOffset) {

        try {
            List<float[]> positions = getPositions(source, keyword);
            //添加水印：会查询到多个关键字定位，固定取最后一个
            addImage(source, target, imagePath, positions.get(positions.size() - 1), xOffset, yOffset);
            log.info("PDF印章工具类:-->findKeyWordAndAddImage:添加水印成功");
        } catch (Exception e) {
            log.error("PDF印章工具类:-->findKeyWordAndAddImage:添加水印失败", e);
        }
    }

    /**
     * @param source
     * @param target
     * @param positions
     * @return
     */
    private static void addKeyWords(String source, String target, float[] positions, String keyWords) throws IOException, DocumentException {
        // 读取模板文件
        InputStream input = new FileInputStream(new File(source));
        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(target));

        // 获取操作的页面
        PdfContentByte under = stamper.getOverContent((int) positions[0]);

        //这个字体是itext-asian.jar中自带的 所以不用考虑操作系统环境问题.
        BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        //baseFont不支持字体样式设定.但是font字体要求操作系统支持此字体会带来移植问题.
        Font font = new Font(bf, 10);
        font.setStyle(Font.BOLD);
        font.getBaseFont();
        //开始写入文本
        under.beginText();
        //设置字体和大小
        under.setFontAndSize(font.getBaseFont(), 9);
        //设置字体颜色
        under.setColorFill(BaseColor.WHITE);
        //设置字体的输出位置
        under.setTextMatrix(positions[1], positions[2]);
        //要输出的text
        under.showText(keyWords);
        under.endText();

        //关闭流
        stamper.close();
        reader.close();
    }


    /**
     * 添加水印(签章)
     *
     * @param source    源pdf文件
     * @param target    目标pdf文件
     * @param imagePath 印章路径
     * @param positions 盖章位置
     * @param xOffset   x轴偏移量(没有则指定为0)
     * @param yOffset   y轴偏移量(没有则指定为0)
     * @throws IOException
     * @throws DocumentException
     */
    private static void addImage(String source, String target, String imagePath, float[] positions, float xOffset, float yOffset) throws IOException, DocumentException {
        // 读取模板文件
        InputStream input = new FileInputStream(new File(source));
        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(target));

        // 提取pdf中的表单
        AcroFields form = stamper.getAcroFields();
        form.addSubstitutionFont(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED));

        // 读图片
        Image image = Image.getInstance(imagePath);
        // 获取操作的页面
        PdfContentByte under = stamper.getOverContent((int) positions[0]);

        //设置图片的定位
        image.setAbsolutePosition(positions[1] + xOffset, positions[2] + yOffset);

        //缩放图片为指定百分比
        image.scalePercent(70);

        // 设置透明度为0.8
        PdfGState gs = new PdfGState();
        gs.setFillOpacity(0.8f);
        under.setGState(gs);
        // 添加图片
        under.addImage(image);

        //关闭流
        stamper.close();
        reader.close();
    }

}
